home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / 4_0 / FINDPRIN / TESTATP.C
C/C++ Source or Header  |  1991-10-22  |  11KB  |  433 lines

  1. #ifdef COMMENT
  2.  
  3.     |    testATP.c
  4.     |
  5.     |    This program scans the AppleTalk network for all LaserPrinter servers
  6.     |    and displays them in a list. This is the Beta-test for a project which
  7.     |    I'm working on currently. I though it might be of interest to those
  8.     |    exploring the preferred AppleTalk interface.
  9.     |
  10.     |    <c>1991 Mike Carter, MCDesign. You may use portions of this code if you like,
  11.     |    as long as authorship is acknowledged. Bug reports and any (and all) comments
  12.     |    are welcome! You can reach me via E-Mail at CompuServe 76114,321.
  13.     |
  14.     |    'FindPrinters' is a trademark of MCDesign. All rightrs reserved.
  15.     |
  16.     
  17. #endif
  18.  
  19. #define SEARCH                1                /* Dialog items */
  20. #define LIST                2
  21. #define NUMFOUND            3
  22. #define DONE                4
  23. #define LINE                8
  24. #define ICON                9
  25. #define MSG                    10
  26.  
  27. #define LOOKING                1                /* Message strings */
  28. #define LOOKUPERR            2
  29. #define EXTRACTERR            3
  30. #define NO_DEVICES            4
  31. #define ALL_DONE            5
  32.  
  33. #define BASE_RES            128
  34. #define NIL_POINTER            0L
  35. #define    WNE_TRAP_NUM        0x60
  36. #define    UNIMPL_TRAP_NUM        0x9F
  37.  
  38. #include <nAppleTalk.h>
  39.  
  40. void DrawTheLine( DialogPtr theDlog );        /* Draws a dotted line on a userItem */
  41. void DoAlert( short );                        /* Changes message area in DLOG */
  42. int findPrinters( Str32 *, short * );        /* does all the ATP stuff */
  43.  
  44. Str32            theObj = "\p=";                    /* Anything... */
  45. Str32            theType = "\pLaserWriter";        /* of type LaserPrinter... */
  46. Str32            theZone = "\p*";                /* in our zone. */
  47. DialogPtr        mainDlog;
  48. GrafPtr            oldPort;
  49. short            maxToGet = 25;                    /* max number to find */
  50. short            numFound = 0;                    /* number found in search */
  51.  
  52. Str32            pNames[25];                        /* array for found printers */
  53. ListHandle        theListH;
  54. Boolean            gDone = false;
  55. Boolean            gWNElmplemented;
  56. EventRecord        gTheEvent;
  57. Ptr                theBuff, ePtr;                    /* NBP receive buffer; entity pointer */
  58. int                buffSize;                        /* size of buffer */
  59. CursHandle        WatchCursor;
  60. Str255    brag = "\pFindPrinters <c>1991 MCDesign. Written by Mike Carter (76114,321) in Think C";
  61.  
  62.  
  63. /*********************** main *****************************/
  64. main()
  65. {
  66.     MaxApplZone();                        /* get some ROOM!!!! */
  67.     InitMac();                            /* initialize Mac Managers */
  68.     
  69.     /* Allocate our main memory-gobbling structures so they end */
  70.     /* up at the bottom of our heap, causing much less heap     */
  71.     /* fragmentation. I call this semi-dynamic allocation!      */
  72.     
  73.     buffSize = (sizeof( EntityName ) + 4) * maxToGet;
  74.  
  75.     theBuff = NewPtrClear( buffSize );
  76.     if( theBuff == 0L ) 
  77.         ExitToShell();                    /* No memory!! */
  78.     
  79.     ePtr = NewPtrClear( 100 );            /* size for NBPSetentitiy */
  80.     if( ePtr == 0L ) 
  81.         ExitToShell();                    /* no memory!! */
  82.     
  83.     SetUpDlog();                        /* load and show our main dialog */
  84.     
  85.     LoopTheLoop();                        /* main event loop */
  86.     
  87.     /* clean-up routines */
  88.     LDispose( theListH );                /* Can't say whether or not these  */
  89.     DisposPtr( ePtr );                    /* are _really_ necessary, seeing  */
  90.     DisposPtr( theBuff );                /* that quitting the app. releases */
  91.     DisposDialog( mainDlog );            /* it's memory anyway--but what the */
  92.                                         /* heck! can't hurt!!                */
  93.     
  94.     SetPort( oldPort );                    /* Set the GrafPort back the way we found it */
  95.         
  96.     ExitToShell();                        /* ta-ta for now */
  97. }
  98.  
  99. /*********************** InitMac **************************/
  100. InitMac()
  101. {
  102.     InitGraf( &thePort );                /* Initialize the Mac Managers */
  103.     InitFonts();
  104.     FlushEvents( everyEvent, 0 );
  105.     InitWindows();
  106.     InitMenus();
  107.     TEInit();
  108.     InitDialogs( 0L );
  109.     InitCursor();
  110.     
  111.     WatchCursor=GetCursor( watchCursor );
  112.     HNoPurge((Handle)WatchCursor);
  113. }
  114.  
  115. /******************** SetUpDlog *****************************/
  116. SetUpDlog()
  117. {
  118.     int            type = 0, hit = 0;
  119.     Rect        box;
  120.     Handle        itemH;
  121.     
  122.     mainDlog = GetNewDialog( BASE_RES + 1, 0L, -1L );    /* Get our main Dialog */
  123.     if( mainDlog == 0L )
  124.         ExitToShell();
  125.     
  126.     GetPort( &oldPort );                /* Let's be port-friendly */
  127.     SetPort( mainDlog );
  128.     
  129.     SetUpList();                        /* define the list which shows the printer names */
  130.     
  131.     ShowWindow( mainDlog );                /* become visual reality */
  132.     DrawDialog( mainDlog );                /* draw the guts */
  133.     
  134.     FrameListRect();                    /* frame the list's rect */
  135.     
  136.     DrawButton( mainDlog );                /* outline the default button */
  137.     DrawTheLine( mainDlog );            /* draw the line seperating the message area */
  138. }
  139.  
  140. /****************** SetUpList ********************************/
  141. SetUpList()
  142. {
  143.     int        type, i;
  144.     Rect    box, dataBounds, rView;
  145.     Point    cSize;
  146.     Handle    itemH;
  147.     Cell    theCell;
  148.     
  149.     GetDItem( mainDlog, LIST, &type, &itemH, &box );
  150.     
  151.     rView = box;                        /* Get rect size from our DITL user item */
  152.     rView.left+=1;                        /* leave room for framerect */
  153.     rView.right-=16;                    /* room for scrool bar and framerect */
  154.     rView.bottom -= 1;                    /* room for framerect */
  155.     
  156.     cSize.h = rView.right - rView.left;                /* set cell size */
  157.     cSize.v = (rView.bottom - rView.top) / 6;        /* show 6 cells at a time */
  158.     
  159.     SetRect(&dataBounds,0,0,1,maxToGet);            /* define cell structure */
  160.     
  161.     theListH = LNew(&rView, &dataBounds, cSize, 0L, mainDlog, true, false, false, true);
  162.     (**theListH).selFlags = lOnlyOne+lNoDisjoint+lNoExtend+lNoNilHilite;
  163.     
  164. }
  165.  
  166. /**************************** LoopTheLoop ***************************/
  167. LoopTheLoop()
  168. {
  169.     /*    MAIN LOOP SEGMENT!!!!!
  170.      *
  171.      *    Is WaitNextEvent() implemented?  If it is, the address of the
  172.      *    WaitNextEvent() trap will be different than the standard,
  173.      *    "unimplemented" trap...
  174.      */
  175.      
  176.     gWNElmplemented = ( NGetTrapAddress( WNE_TRAP_NUM, ToolTrap ) !=
  177.                             NGetTrapAddress( UNIMPL_TRAP_NUM, ToolTrap ) );
  178.     
  179.     /*
  180.      *    Don't wait for a mouse click. Retrieve and process events
  181.      *    instead!
  182.      */
  183.  
  184.     while ( gDone == false )
  185.     {
  186.         HandleEvent();
  187.     }
  188. }
  189.  
  190. /************************** HandleEvent *****************************/
  191. HandleEvent()
  192. {
  193.     int        theItem, type;
  194.     Handle    itemH;
  195.     Rect    box;
  196.     Point    pt;
  197.     int        err = 0;
  198.  
  199.     if ( gWNElmplemented )                        /* Use appropriate event routine */
  200.         WaitNextEvent( everyEvent, &gTheEvent, 0L, 0L );
  201.     
  202.     else
  203.     {
  204.         SystemTask();
  205.         GetNextEvent( everyEvent, &gTheEvent );
  206.     }
  207.  
  208.     if (IsDialogEvent( &gTheEvent ) )            /* event happened inside the Dlog?? */
  209.     {
  210.         if ( DialogSelect( &gTheEvent, &mainDlog, &theItem ) )        /* yes it did!! */
  211.         {
  212.             switch( theItem )
  213.             {
  214.                 case SEARCH:
  215.                     SetCursor(*WatchCursor);
  216.                     err = findPrinters( pNames, &numFound );
  217.                     InitCursor();
  218.                     if( err != noErr)
  219.                         SysBeep( 30 );
  220.                     break;
  221.                     
  222.                 case DONE:
  223.                     gDone = true;
  224.                     return;                /* fall all the out to LoopTheLoop */
  225.                     break;
  226.                     
  227.                 case LIST:
  228.                     pt = gTheEvent.where;
  229.                     GlobalToLocal( &pt );
  230.                     LClick( pt, gTheEvent.modifiers, theListH );
  231.                     break;
  232.                     
  233.                 case ICON:
  234.                     GetDItem( mainDlog, MSG, &type, &itemH, &box );    /* secret brag switch! */
  235.                     SetIText( itemH, &brag );
  236.                     break;
  237.             }
  238.             gTheEvent.what = nullEvent;        /* so the following switch won't handle it */
  239.         }
  240.     }
  241.         
  242.     switch ( gTheEvent.what )        /* Okay, event wasn't part of dialog */
  243.     {
  244.         case nullEvent:
  245.             break;
  246.  
  247.         case mouseDown:
  248.             HandleMouseDown();
  249.             break;
  250.         
  251.         case keyDown:                /* don't need to list them */
  252.         case keyUp:
  253.         case autoKey:
  254.             break;
  255.             
  256.         case updateEvt:
  257.             BeginUpdate( gTheEvent.message );
  258.             DrawDialog( mainDlog );
  259.             FrameListRect();
  260.             EndUpdate( gTheEvent.message );
  261.             break;
  262.     }
  263. }
  264.  
  265. /*********************** HandleMouseDown ******************/
  266. HandleMouseDown()
  267. {
  268.         WindowPtr    whichWindow;
  269.         short int    thePart;
  270.         long        windSize;
  271.         GrafPtr        oldPort;
  272.         Rect        dragRect = screenBits.bounds;
  273.  
  274. /*    First, find out which window the mouse click occurred in.
  275.  *    Then, find out what part of the window the mouse click occurred in.
  276.  */
  277.  
  278.     thePart = FindWindow( gTheEvent.where, &whichWindow );
  279.     switch ( thePart )
  280.     {
  281.         case inSysWindow :             /*    Probably a desk accessory window... */
  282.             SystemClick( &gTheEvent, whichWindow );
  283.             break;
  284.             
  285.         case inDrag:                /* Drag the window around the screen, limited by dragRect */
  286.             DragWindow( whichWindow, gTheEvent.where, &dragRect);
  287.             break;
  288.     }
  289. }
  290.  
  291. /**************************** FrameListRec **************************/
  292. FrameListRect()
  293. {
  294.     int        type;
  295.     Rect    box;
  296.     Handle    itemH;
  297.     
  298.     GetDItem( mainDlog, LIST, &type, &itemH, &box );
  299.     box.top -= 1;
  300.     FrameRect( &box );
  301.     
  302.     DisposHandle( itemH );
  303. }
  304.  
  305. /************************** findPrinters ****************************/
  306. int findPrinters( Str32 *pNames, short *numFound)
  307. {
  308.     EntityName        aFoundPrinter;            /* holds info for found printers */
  309.     AddrBlock        entityAddr;                /* address for found printers */
  310.     int                type = 0, i = 0;        /* Dlog stuff */
  311.     long            dummy;                    /* Delay() dummy var */
  312.     Handle            itemH;                    /* Dlog stuff */
  313.     Rect            box;                    /* ditto. */
  314.     Str255            look, numStr;                /* a mesage */
  315.     MPPParamBlock    p;                        /* preferred interface paramBlock */
  316.     Ptr                ePtr;                    /* pointer to entity stuff */
  317.     OSErr            err;                    /* OS err value */
  318.     Cell            theCell;                /* for the Dlog list */
  319.  
  320.     GetIndString(  &look, BASE_RES, LOOKING );        /* load a message */
  321.     GetDItem( mainDlog, MSG, &type, &itemH, &box );
  322.     SetIText( itemH, &look );
  323.  
  324.     
  325.     NBPSetEntity( ePtr, theObj, theType, theZone );        /* setup up the entity */
  326.     
  327.     p.ioCompletion = 0L;                /* no completion procedure */
  328.     p.NBPinterval = 2;                    /* interval of two */
  329.     p.NBPcount = 3;                        /* retry three times only */
  330.     p.NBPentityPtr = ePtr;                /* the entity info */
  331.     p.NBPretBuffPtr = theBuff;            /* return buffer */
  332.     p.NBPretBuffSize = buffSize;
  333.     p.NBPmaxToGet = maxToGet;            /* maximum entities to find */
  334.     
  335.     err = PLookupName( &p, false );        /* go lookin' */
  336.     if( err != noErr )
  337.     {
  338.         DoAlert( LOOKUPERR );
  339.         return( -1 );
  340.     }
  341.     
  342.     if( p.NBPnumGotten <= 0 )
  343.     {
  344.         DoAlert( NO_DEVICES );                    /* error code for none found */
  345.         return( -1 );
  346.     }
  347.     
  348.     NumToString( p.NBPnumGotten, &numStr  );
  349.     GetDItem( mainDlog, NUMFOUND, &type, &itemH, &box );
  350.     SetIText( itemH, &numStr );
  351.     
  352.     for( i = 1; i <= p.NBPnumGotten; i++ )    /* cycle thru and extract */
  353.     {
  354.         err = NBPExtract( theBuff, p.NBPnumGotten, i, &aFoundPrinter, &entityAddr );
  355.         if( err != noErr )
  356.         {
  357.             DoAlert( EXTRACTERR );
  358.             return( -1 );
  359.         }
  360.             
  361.         BlockMove( (Ptr)&aFoundPrinter.objStr, (Ptr)&pNames[i], aFoundPrinter.objStr[0] );
  362.         theCell.h = 0; theCell.v = i - 1;
  363.         LSetCell( (Ptr)&aFoundPrinter.objStr[1], aFoundPrinter.objStr[0], theCell, theListH );
  364.         LDraw( theCell, theListH );
  365.     } 
  366.     
  367.     GetIndString(  &look, BASE_RES, ALL_DONE );        /* load a message */
  368.     GetDItem( mainDlog, MSG, &type, &itemH, &box );
  369.     SetIText( itemH, &look );
  370.  
  371.     return( 0 );        /* all is well */
  372. }
  373.  
  374. /*********************** DoAlert ************************/
  375. void DoAlert( short index )
  376. {
  377.     int        type;
  378.     Rect    box;
  379.     Handle    itemH;
  380.     Str255    errStr;
  381.     
  382.     GetDItem( mainDlog, MSG, &type, &itemH, &box );
  383.     GetIndString( &errStr, BASE_RES, index );
  384.     
  385.     SetIText( itemH, &errStr );
  386.     DisposHandle( itemH );
  387. }
  388.  
  389.  
  390. /********************** DrawTheLine ***********************/
  391. void DrawTheLine( DialogPtr theDlog )
  392. /* 
  393.     |    This function will, utilizing the Rect defined in the user item
  394.     |    within the rez file, draw a dotted line to seperate the message
  395.     |    line at the bottom of the DLOG from the parts above it.
  396. */
  397. {
  398.     Handle    itemH;
  399.     Rect    box, theRect;
  400.     Point    where, left, right;
  401.     int        type;
  402.     
  403.     GetDItem( theDlog, LINE, &type, &itemH, &box );
  404.     
  405.     PenPat( ltGray );
  406.     PenSize( 1, 1 );
  407.     
  408.     MoveTo( box.left, box.top );
  409.     LineTo( box.right, box.top );
  410.     
  411.     PenNormal();
  412. }
  413.  
  414. /*************************** ButtonDraw ****************/
  415. DrawButton( theDialog )
  416. DialogPtr    theDialog;
  417. {
  418.     int        itemType;
  419.     Rect    itemRect;
  420.     Handle    item;
  421.     GrafPtr    oldPort;
  422.     
  423.     GetDItem( theDialog, SEARCH, &itemType, &item, &itemRect );
  424.     GetPort( &oldPort );
  425.     SetPort( theDialog );
  426.     
  427.     PenSize( 3,3 );
  428.     InsetRect( &itemRect, -4, -4 );
  429.     FrameRoundRect( &itemRect, 16, 16 );
  430.     PenNormal();
  431.     
  432.     SetPort( oldPort );
  433. }